package test.com.newproject.tool.helper;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.IntentUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;

import java.io.File;

import library.com.httphelper.HttpHelper;
import test.com.newproject.model.Constant;
import test.com.newproject.model.beans.UpdateBean;
import test.com.newproject.ui.DownloadDialog;


/**
 * desc: 版本更新（稳定版本 v 1.0）
 * author:zjh
 * date:2017/12/5
 * time:9:20
 */
public enum UpdateHelper {
    INSTANCE;

    protected Context context;
    protected String downloadUrl;
    protected long downloadId;
    protected DownloadManager dm;
    protected DownloadManager.Request request;
    protected DownloadDialog downloadDialog;
    protected Dialog errDialog;
    protected CompletetReceiver completetReceiver;
    protected DownloadContentObserver downloadContentObserver;
    protected File downloadFile;
    protected UpdateBean data;

    //是否强制更新（1:强制 0:非强制）
    protected int isForceUpdate;

    private boolean register = false;
    private boolean failed = false;
    private static final String DOWNLOAD_TITLE = "财位";
    private static final String DIR_TYPE = Environment.DIRECTORY_DOWNLOADS;
    private static final String FILE_NAME = "caiwei.apk";
    private static final Uri URI_DOWNLOAD = Uri.parse("content://downloads/my_downloads");


    public void checkVersion(final Context context) {
        if (context == null) {
            LogUtils.iTag("UpdateHelper", "update error:context == null");
            return;
        }

        this.context = context;
        this.dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        long apkDownloadId = SPUtils.getInstance().getLong("APK_DOWNLOAD_ID", -1);
        LogUtils.iTag("UpdateHelper", "complete apkDownloadId:" + apkDownloadId);
        if (apkDownloadId > 0) {
            //移除历史任务以及文件
            //remove方法只是通知系统去移除任务，是异步的
            //所以remove之后依然还是要判断文件是否存在
            dm.remove(apkDownloadId);
            SPUtils.getInstance().put("APK_DOWNLOAD_ID", -1);
            LogUtils.iTag("UpdateHelper", "remove apkDownloadId:" + apkDownloadId);
        }

        HttpHelper.DEFAULT.execute(new HttpHelper.Request<Object>("url", null) {
            @Override
            public void onSuccess(Object reslut) {
                parseVersion(null);
            }

            @Override
            public void onError(int code, String err) {
                super.onError(code, err);
                LogUtils.iTag("UpdateHelper", "update error:call error:" + err);
            }
        });
    }

    private void parseVersion(UpdateBean data) {
        this.data = data;
        this.isForceUpdate = data.getIsForceUpdate();
        int latestVersion = 0, localVersion = 0;
        try {
            latestVersion = Integer.parseInt(data.getLatestVersion());
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.iTag("UpdateHelper", "update error:latestVersion error:" + e.getMessage());
        }

        localVersion = AppUtils.getAppVersionCode();

        //接口版本低于本地版本无需更新
        if (latestVersion <= localVersion) {
            LogUtils.iTag("UpdateHelper", "update finish:latestVersion <= localVersion");
            return;
        }

        this.downloadUrl = data.getDownloadUrl();

        if (TextUtils.isEmpty(downloadUrl)) {
            LogUtils.iTag("UpdateHelper", "update error:downloadUrl error:null");
            return;
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setCancelable(isForceUpdate == 1 ? false : true)
                .setTitle("提示")
                .setMessage("发现新版本了，马上更新吧")
                .setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        try {
                            startDownLoad();
                        } catch (Exception e) {
                            e.printStackTrace();
                            LogUtils.iTag("UpdateHelper", "update error:startDownLoad error:" + e.getMessage());
                        }
                    }
                });

        if (isForceUpdate != 1) {
            builder.setNegativeButton("稍后再说", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            });
        }

        builder.show();
    }

    private void startDownLoad() {
        downloadFile = new File(context.getExternalFilesDir(DIR_TYPE) + "/" + FILE_NAME);
        request = createRequest();
        completetReceiver = new CompletetReceiver();
        //接受下载完成的广播
        context.registerReceiver(completetReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        downloadContentObserver = new DownloadContentObserver(new Handler());
        //监听下载进度
        context.getContentResolver().registerContentObserver(URI_DOWNLOAD, true, downloadContentObserver);
        register = true;
        LogUtils.iTag("UpdateHelper", "update:register:true");

        //由于DownloadManager的remove并不是立刻删除文件
        //所以还是要判断一次历史下载的文件是否存在
        if (FileUtils.isFile(downloadFile)) {
            LogUtils.iTag("UpdateHelper", "file exist");
            FileUtils.deleteFile(downloadFile);
            LogUtils.iTag("UpdateHelper", "file delete");
        }

        downloadId = dm.enqueue(request);
        failed = false;
        SPUtils.getInstance().put("APK_DOWNLOAD_ID", downloadId);
        showDownload(context);
    }

    private DownloadManager.Request createRequest() {
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl));
        //指定路径
        request.setDestinationInExternalFilesDir(context.getApplicationContext(), DIR_TYPE, FILE_NAME);
        //显示Notification
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        request.setTitle(DOWNLOAD_TITLE);
        request.setDescription("新版本下载中...");
        //设置类型
        request.setMimeType("application/vnd.android.package-archive");
        //设置执行状态
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
        //设置可被扫描
        request.allowScanningByMediaScanner();
        //设置为可见
        request.setVisibleInDownloadsUi(true);

        return request;
    }

    public void showDownload(Context context) {
        downloadDialog = new DownloadDialog(context, data.getIsForceUpdate());
        downloadDialog.setTitle("版本升级");
        downloadDialog.setTips("正在下载，请稍等...");
        downloadDialog.show();
    }


    private void queryDownload() {
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor cursor = dm.query(query);
        if (cursor == null || !cursor.moveToFirst()) {
            return;
        }

        int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
        switch (status) {
            case DownloadManager.STATUS_PAUSED:
                ToastUtils.showLong("您的版本更新已暂停");
                break;
            case DownloadManager.STATUS_PENDING:
                break;
            case DownloadManager.STATUS_RUNNING:
                break;
            case DownloadManager.STATUS_SUCCESSFUL:
                break;
            case DownloadManager.STATUS_FAILED:
                failed = true;
                finish();
                int reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON));
                String errMsg = "未知";
                switch (reason) {
                    case 404:
                    case DownloadManager.ERROR_HTTP_DATA_ERROR:
                    case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
                        errMsg = "错误的更新链接";
                        break;
                    case DownloadManager.ERROR_INSUFFICIENT_SPACE:
                        errMsg = "空间不足";
                        break;
                    case DownloadManager.ERROR_FILE_ALREADY_EXISTS:
                        errMsg = "更新文件已存在";
                        break;
                    case DownloadManager.ERROR_FILE_ERROR:
                        errMsg = "更新文件错误";
                        break;
                    case DownloadManager.ERROR_UNKNOWN:
                        errMsg = "未知";
                        break;
                    default:
                        errMsg = "未知";
                        break;
                }

                if (errDialog == null || !errDialog.isShowing()) {
                    errDialog = new AlertDialog.Builder(context)
                            .setCancelable(isForceUpdate == 1 ? false : true)
                            .setTitle("提示")
                            .setMessage(String.format("版本更新失败：%s\r\n十分抱歉给您带来不便，您可稍后重试或选择应用市场进行更新", errMsg))
                            .setPositiveButton("知道了", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    dialogInterface.dismiss();
                                    if (isForceUpdate == 1) {
                                        AppUtils.exitApp();
                                    }
                                }
                            }).show();
                }

                return;
            default:
                break;
        }

        int downloadSize = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
        int totalSize = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
        float progress = downloadSize / ((float) totalSize);

        if (downloadDialog == null || !downloadDialog.isShowing()) {
            return;
        }

        downloadDialog.refreshProgress(progress);
    }

    class DownloadContentObserver extends ContentObserver {

        /**
         * Creates a content observer.
         *
         * @param handler The handler to run {@link #onChange} on, or null if none.
         */
        public DownloadContentObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            LogUtils.iTag("UpdateHelper", "update:onChange:failed:" + failed + "selfChange:" + selfChange);
            if (!failed) {
                try {
                    queryDownload();
                } catch (Exception e) {
                    e.printStackTrace();
                    LogUtils.iTag("UpdateHelper", "update error:queryDownload error:" + e.getMessage());
                }
            }
        }
    }

    class CompletetReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            long completeId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            if (downloadId != completeId) {
                return;
            }

            finish();

            installApk();
        }
    }

    public void installApk() {
        if (!FileUtils.isFile(downloadFile) || downloadFile.length() <= 0) {
            return;
        }

        Intent intent = null;
        try {
            intent = IntentUtils.getInstallAppIntent(downloadFile, Constant.FILE_PROVIDER_AUTHORITIES);
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.iTag("UpdateHelper", "update error:install error:" + e.getMessage());
        }
    }

    /**
     * 在调用的Activity（一般是MainActivity）onDestory时调用此方法
     */
    public void finish() {
        try {
            if (downloadDialog != null) {
                downloadDialog.dismiss();
            }

            if (register) {
                register = false;
                if (context != null && downloadContentObserver != null) {
                    context.getContentResolver().unregisterContentObserver(downloadContentObserver);
                }

                if (context != null && completetReceiver != null) {
                    context.unregisterReceiver(completetReceiver);
                }
            }
        } catch (Exception e) {
            LogUtils.iTag("UpdateHelper", "finish error:" + e.getMessage());
        }
    }
}
